//
//  XFYCropImageView.m
//  SDKSample
//
//  Created by 小肥羊 on 15/6/30.
//  Copyright (c) 2015年 Zhu‘s Game House. All rights reserved.
//

#import "XFYCropImageView.h"

#define kMaskViewBorderWidth    (2.0f)

#pragma mark - 裁剪框
@implementation XFYCropImageMaskView

- (void)setCropSize:(CGSize)size
{
    CGFloat x = (CGRectGetWidth(self.bounds) - size.width) / 2;
    CGFloat y = (CGRectGetHeight(self.bounds) - size.height) / 2;
    self.cropRect = CGRectMake(x, y, size.width, size.height);
    [self setNeedsDisplay];
}

- (CGSize)cropSize
{
    return self.cropRect.size;
}

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(ctx, 1, 1, 1, .6);
    CGContextFillRect(ctx, self.bounds);
    
    CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextStrokeRectWithWidth(ctx, self.cropRect, kMaskViewBorderWidth);
    
    CGContextClearRect(ctx, self.cropRect);
}

@end

#pragma mark - 裁剪视图
@implementation XFYCropImageView
#pragma mark - 惰性初始化
- (UIScrollView *)scrollView
{
    if (!_scrollView) {
        _scrollView = [[UIScrollView alloc] init];
        [_scrollView setDelegate:self];
        [_scrollView setBounces:NO];
        [_scrollView setShowsHorizontalScrollIndicator:NO];
        [_scrollView setShowsVerticalScrollIndicator:NO];
        [self addSubview:_scrollView];
    }
    return _scrollView;
}

- (UIImageView *)imageView
{
    if (!_imageView) {
        _imageView = [[UIImageView alloc] init];
        [self.scrollView addSubview:_imageView];
    }
    return _imageView;
}

- (XFYCropImageMaskView *)maskView
{
    if (!_maskView) {
        _maskView = [[XFYCropImageMaskView alloc] init];
        [_maskView setBackgroundColor:[UIColor clearColor]];
        [_maskView setUserInteractionEnabled:NO];
        [self addSubview:_maskView];
        [self bringSubviewToFront:_maskView];
    }
    return _maskView;
}

#pragma mark - Set
- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];
    [self.scrollView setFrame:self.bounds];
    [self.maskView setFrame:self.bounds];
    
    if (CGSizeEqualToSize(self.cropSize, CGSizeZero)) {
        self.cropSize = CGSizeMake(100, 100);
    }
}

- (void)setImage:(UIImage *)image {
    _image = image;
    [self.imageView setImage:_image];
    [self updateZoomScale];
}

- (void)setCropSize:(CGSize)cropSize
{
    _cropSize = cropSize;
    [self updateZoomScale];
    
    CGFloat width = _cropSize.width;
    CGFloat height = _cropSize.height;
    
    CGFloat x = (CGRectGetWidth(self.bounds) - width) / 2;
    CGFloat y = (CGRectGetHeight(self.bounds) - height) / 2;
    
    [self.maskView setCropSize:_cropSize];
    
    CGFloat top = y;
    CGFloat left = x;
    CGFloat right = CGRectGetWidth(self.bounds)- width - x;
    CGFloat bottom = CGRectGetHeight(self.bounds)- height - y;
    self.imageInset = UIEdgeInsetsMake(top, left, bottom, right);
    [self.scrollView setContentInset:self.imageInset];
    [self.scrollView setContentOffset:CGPointMake(0, 0)];
}

- (void)updateZoomScale {
    CGFloat width = self.image.size.width;
    CGFloat height = self.image.size.height;
    
    [self.imageView setFrame:CGRectMake(0, 0, width, height)];
    
    CGFloat xScale = self.cropSize.width / width;
    CGFloat yScale = self.cropSize.height / height;
    
    CGFloat min = MAX(xScale, yScale);
    CGFloat max = 1.0;
    if (min > max) {
        min = max;
    }
    [self.scrollView setMinimumZoomScale:min];
    [self.scrollView setMaximumZoomScale:max];
    [self.scrollView setZoomScale:min animated:YES];
}

- (UIImage *)cropImage {
    CGFloat zoomScale = self.scrollView.zoomScale;
    
    CGFloat offsetX = self.scrollView.contentOffset.x;
    CGFloat offsetY = self.scrollView.contentOffset.y;
    CGFloat aX = offsetX>=0 ? offsetX+_imageInset.left : (_imageInset.left - ABS(offsetX));
    CGFloat aY = offsetY>=0 ? offsetY+_imageInset.top : (_imageInset.top - ABS(offsetY));
    
    aX = aX / zoomScale;
    aY = aY / zoomScale;
    
    CGFloat aWidth = MIN(_cropSize.width / zoomScale, _cropSize.width);
    CGFloat aHeight = MIN(_cropSize.height / zoomScale, _cropSize.height);
    if (zoomScale < 1)
    {
        aWidth = MAX(_cropSize.width / zoomScale, _cropSize.width);
        aHeight = MAX(_cropSize.height / zoomScale, _cropSize.height);
    }
    UIImage *image = [[self fixOrientation:self.image] cropImageWithX:aX y:aY width:aWidth height:aHeight];
    //image = [image resizeToWidth:self.cropSize.width height:self.cropSize.height];    不用这句话
    return image;
}

#pragma UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.imageView;
}

#pragma mark - 方法
- (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize
{
    UIGraphicsBeginImageContext(CGSizeMake(image.size.width * scaleSize, image.size.height * scaleSize));
    [image drawInRect:CGRectMake(0, 0, image.size.width * scaleSize, image.size.height * scaleSize)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}
/*! @brief 还原旋转图 */
- (UIImage *)fixOrientation:(UIImage *)aImage {
    
    // No-op if the orientation is already correct
    if (aImage.imageOrientation == UIImageOrientationUp)
        return aImage;
    
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }
    
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
